﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Drawing;
using System.Windows.Forms;
using System.IO;

namespace RefOffDesktop
{
    /*
     * Class: VirtualPitchMapper
     * 
     * Use: Used to map locations for whistles and incidents within a Match, onto a
     *      'Virtual Pitch', based on two GPS location sentences.
     *      
     * Author: This class is based on the 'Mapper' class from the 'GPS Tracer' application,
     *         by Leonardo Salvatore. This is freely available at:
     *      
     *         http://www.codeproject.com/KB/mobile/GpsTracerAppWMCE5.aspx
     *      
     *         Modifications to the original class that this class was formed from are
     *         indicated within the code.
     *         
     *         NOTE: All comments were added by Mike Skaife, mcs3@aber.ac.uk
     */      
    class VirtualPitchMapper
    {
        private List<Point> m_points;
        private Point m_center;

        //MODIFICATION: m_drawded initialised to 1 rather than 0
        int m_drawded = 1;
        private Graphics m_g;
        private Rectangle m_clip;

        //Global variables unmodified, used in drawing graphics objects
        //within the class
        static private Pen m_bgPen = new Pen(Color.Transparent);
        static private Pen m_gridPen = new Pen(Color.Green);
        static private Brush m_bgBrush = new SolidBrush(m_bgPen.Color);
        static private Pen m_linePen = new Pen(Color.Red);
        static private Pen m_pointPen = new Pen(Color.Red);
        static private Pen m_lastPointPen = new Pen(Color.Red);
        static private Font m_font = new Font("Tahoma", 8, FontStyle.Regular);
        static private Brush m_fontBrush = new SolidBrush(Color.Yellow);
        
        public VirtualPitchMapper(Graphics g, int x, int y, int width, int height)
        {
            m_points = new List<Point>();

            //MODIFICATION: Following line removed, replaced with line below,
            //              to set origin as top left corner of Virtual Pitch
            //m_center = new Point(x + width / 2, y + height / 2);
            m_center = new Point(0, 0);
            m_g = g;
            m_clip = new Rectangle(x, y, width, height);
            m_g.Clip = new Region(m_clip);

            //MODIFICATION: Following line modified to pass in
            //              required input parameter
            clearAndDraw(m_points);
        }

        //MODIFICATION: Added Point as a return parameter from method
        public Point parseAndDraw(string s)
        {
            //MODIFICATION: Following line added
            Point newPoint = new Point();

            string[] Words = s.Split(',');

            m_g.FillRectangle(m_bgBrush, new Rectangle(m_clip.X, m_clip.Y + 5, m_clip.Width, 15));
            m_g.DrawString(s, m_font,m_fontBrush, new RectangleF(m_clip.X , m_clip.Y + 5, m_clip.Width, 15));

            switch (Words[0])
            {
                case "$GPRMC":// $GPRMC,170111,A,4338.5810,N,07015.1010,W,000.0,360.0,060199,017.5,W*73
                    // RMC - Recommended minimum specific GPS/Transit data

                    if (Words[3].Length > 0 && Words[5].Length > 0)
                    {
                        //MODIFICATION: Following line removed, replaced with line below
                        //drawLatLong(Words[3], Words[5]);
                        newPoint = drawLatLong(Words[3], Words[5]);
                    }
                    break;
                case "$GPGSV":// $GPGSV,2,1,08,03,17,171,42,06,21,047,44,14,28,251,45,16,25,292,44*71
                    // GSV - Satellites in view
                    break;
                case "$GPGSA":// $GPGGA,170111,4338.581,N,07015.101,W,1,00,2.0,1.1,M,-31.8,M,,*71
                    //GSA - GPS dilution of precision and active satellites
                    break;
                default:
                    break;
            }

            //MODIFICATION: Following line added to return the Point
            return newPoint;
        }
        
        //MODIFICATION: Method now returns a single Point, rather than 'void'
        //
        //This method creates a Point, consisting of an X and Y co-ordinate, which
        //will ultimately be displayed on the Virtual Pitch. These co-ordinates are
        //calculated by converting the GPS longitude and latitude into decimal format,
        //in the following way: Degrees + (Mins/60) + (Seconds/3600)
        public Point drawLatLong(string latitude, string longitude)
        {
            Point aPoint = new Point();

            aPoint.X = (Convert.ToInt32(latitude.Substring(latitude.Length - 4, 4)));
            aPoint.Y = (Convert.ToInt32(longitude.Substring(longitude.Length - 4, 4)));

            aPoint.X += (Convert.ToInt32(latitude.Substring(latitude.Length - 7, 2))) * 60;
            aPoint.Y += (Convert.ToInt32(longitude.Substring(longitude.Length - 7, 2))) * 60;

            aPoint.X += (Convert.ToInt32(latitude.Substring(latitude.Length - 9, 2))) * 3600;
            aPoint.Y += (Convert.ToInt32(longitude.Substring(longitude.Length - 9, 2))) * 3600;

            //MODIFICATION: Following lines removed - no longer required
            //m_points.Add(aPoint);
            //draw();

            //MODIFICATION: Following line added, so a Point is returned
            //              by the method
            return aPoint;
        }

        //MODIFICATION: Added a List of Points as an input parameter
        //
        //Method used to map whistle and incident onto Virtual Pitch. List
        //of two Points passed to method, which are then mapped onto graphics
        //canvas, based on their X and Y co-ordinates, and a specified scale
        public void draw(List<Point> thePoints)
        {
            //MODIFICATION: Following line added to get hold of
            //List of Points passed to the method
            m_points = thePoints;
            
            float xTo = 0;
            float xFrom = 0;
            float yTo = 0;
            float yFrom = 0;
             
            //MODIFICATION: Following line added to draw pitch as 'background' image
            m_g.DrawImage(Image.FromFile(@"Resources\vpitch.jpg"), new Rectangle(0, 0, 600, 383));

            for (int i = m_drawded; i < m_points.Count; i++)
            {
                xTo = (m_points[i].X - m_points[0].X) / m_scale + m_center.X;
                xFrom = (m_points[i - 1].X - m_points[0].X) / m_scale + m_center.X;
                yTo = (m_points[i].Y - m_points[0].Y) / m_scale + m_center.Y;
                yFrom = (m_points[i - 1].Y - m_points[0].Y) / m_scale + m_center.Y;
                //MODIFICATION: Following two lines removed and replaced with line below,
                //              to draw whistle symbol
                //m_g.DrawLine(m_linePen, (int)xTo, (int)yTo, (int)xFrom, (int)yFrom);
                //m_g.DrawEllipse(m_pointPen, new Rectangle((int)xFrom - 2, (int)yFrom - 2, 4, 4));
                m_g.DrawImageUnscaled(Image.FromFile(@"Resources\vp_whistle.png"),new Rectangle((int)xFrom -2, (int)yFrom -2, 4, 4));
            }

            //MODIFICATION: Following line removed and replace with line below,
            //              to draw incident symbol
            //m_g.DrawEllipse(m_lastPointPen, new Rectangle((int)xTo - 2, (int)yTo - 2, 4, 4));
            m_g.DrawImageUnscaled(Image.FromFile(@"Resources\vp_ball.png"), new Rectangle((int)xTo - 2, (int)yTo - 2, 4, 4));

            //MODIFICATION: Following line removed - no longer required
            //m_drawded++;
        }

        private float m_scale = 100;

        public float Scale
        {
            get { return m_scale; }
            set { m_scale = value; }
        }

        //MODIFICATION: Added List of Points as an input parameter
        public void clearAndDraw(List<Point> thePoints)
        {
            //MODIFICATION: Following line removed - no longer required
            //m_g.FillRectangle(m_bgBrush, m_clip);
            m_drawded = 1;


            //MODIFICATION: Following line changed to pass in required
            //              input parameter to draw() method
            draw(thePoints);
        }

        //MODIFICATION: Removed moveCenter() method - no longer required

        //MODIFICATION: Removed centerInMiddle() method - no longer required

        //MODIFICATION: Removed loatPath() method - no longer required

        //MODIFICATION: Removed savePath() method - no longer required

        public void clearPoints()
        {
            m_points.Clear();
        }
    }
}
